package org.qydjk.console.controller.wechatPublicNumber;

import org.qydjk.common.constant.RedisConstant;
import org.qydjk.common.constant.WechatConstant;
import org.qydjk.common.controller.BaseController;
import org.qydjk.common.pojo.WechatPublicContent;
import org.qydjk.common.pojo.WechatPublicInteraction;
import org.qydjk.common.pojo.WechatUserinfo;
import org.qydjk.common.util.RedisTemplateUtil;
import org.qydjk.common.util.StringUtil;
import org.qydjk.common.util.wechat.WechatMessageUtil;
import org.qydjk.common.util.wechat.WechatSignUtil;
import org.qydjk.common.util.wechat.WechatUtil;
import org.qydjk.common.vo.wechat.Article;
import org.qydjk.common.vo.wechat.ImageMessage;
import org.qydjk.common.vo.wechat.TextMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/qywechat")
public class WechatController extends BaseController{
    @Autowired
    private RedisTemplateUtil redisTemplateUtil;

    //GET请求用于微信的验证
    @RequestMapping(value = "/index",method = RequestMethod.GET)
    public String index1(String type,String code){
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");

        // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
        if (WechatSignUtil.checkSignature(redisTemplateUtil.getWithByte(RedisConstant.WECHAT_PUBLIC_APP_TOKEN_KEY).toString(),signature, timestamp, nonce)) {
            output(echostr);
            logger.info("微信服务验证成功！");
        }
        return null;
    }

    //POST请求用于接收微信的参数
    @RequestMapping(value = "/index",method = RequestMethod.POST)
    public String index2(String type,String code) throws Exception{
        //xml请求解析
        Map<String, Object> requestMap = WechatMessageUtil.parseXml(request);
        //发送方帐号（open_id）
        String fromUserName = requestMap.get("FromUserName").toString();
        //公众帐号
        String toUserName = requestMap.get("ToUserName").toString();
        //消息类型，text，voice，event
        String msgType = requestMap.get("MsgType").toString();
        //事件对应的类型event下的具体类型：subscribe，scan，click
        String event = requestMap.get("Event").toString();
        //事件具体的key：二维码值或者点击的菜单值
        String eventKey = requestMap.get("EventKey").toString();

        logger.info("----wechat msgType :"+msgType);
        logger.info("----wechat event :"+event);
        logger.info("----wechat eventKey :"+eventKey);

        String resMsg = "";

        if (msgType.equals(WechatMessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
            //文本消息
            String content = requestMap.get("Content").toString();
            resMsg = messageFromSql(content, WechatMessageUtil.REQUST_EVENT_TYPE_KEYWORD, fromUserName, toUserName);
//            resMsg = textMessageFromSql(content);
//            logger.info("wechat text :"+content);
        }else if(msgType.equals(WechatMessageUtil.REQ_MESSAGE_TYPE_LOCATION)){
            //位置消息
            //Location_X地理位置维度；Location_Y地理位置经度；Scale地图缩放大小；Label地理位置信息
//            String Location_X = requestMap.get("Location_X").toString();
//            String Location_Y = requestMap.get("Location_Y").toString();
//            String Scale = requestMap.get("Scale").toString();
            String Label = requestMap.get("Label").toString();

            resMsg = messageFromSql(eventKey, WechatMessageUtil.REQUST_EVENT_TYPE_LOCATION, fromUserName, toUserName);

//            logger.info("wechat location: xy="+ Location_X + "," + Location_Y + ";Scale=" + Scale + ";Label=" + Label);
        }else if(msgType.equals(WechatMessageUtil.REQ_MESSAGE_TYPE_VOICE)){
            //语音消息
            //MediaId 语音消息媒体id，可以调用多媒体文件下载接口拉取数据； Format	语音格式，如amr，speex等；MsgID	消息id，64位整型；Recognition	语音识别结果，UTF8编码(需开通语音识别)；
            String MediaId = requestMap.get("MediaId").toString();
            String Format = requestMap.get("Format").toString();
            String MsgID = requestMap.get("MsgID").toString();
            String Recognition = requestMap.get("Recognition").toString();

            resMsg = messageFromSql(Recognition, WechatMessageUtil.REQUST_EVENT_TYPE_KEYWORD, fromUserName, toUserName);

//            logger.info("wechat voice: MediaId="+ MediaId + ";Format=" + Format + ";MsgID=" + MsgID + ";Recognition=" + Recognition);
        }else if(msgType.equals(WechatMessageUtil.REQ_MESSAGE_TYPE_EVENT)){
            //事件消息
            if(event.equals(WechatMessageUtil.EVENT_TYPE_CLICK)){

                resMsg = messageFromSql(eventKey, WechatMessageUtil.REQUST_EVENT_TYPE_CLICK, fromUserName, toUserName);

                //菜单点击
//                logger.info("wechat 菜单点击--" + eventKey);
            }else if(event.equals(WechatMessageUtil.EVENT_TYPE_SCAN)){

//                //已关注扫描专属二维码
//                logger.info("wechat 已关注扫码01--" + eventKey);
//
//                logger.info("wechat 已关注扫码02--" + eventKey);

                if (StringUtil.isEmptyOrNull(eventKey)) {
                    resMsg = messageFromSql(eventKey, WechatMessageUtil.REQUST_EVENT_TYPE_COMMON_CONCERN, fromUserName, toUserName);
                } else {
                    eventKey = eventKey.replace("qrscene_", "");
                    resMsg = messageFromSql(eventKey, WechatMessageUtil.REQUST_EVENT_TYPE_PARAMETER_FOLLOW, fromUserName, toUserName);
                }

            }else if(event.equals(WechatMessageUtil.EVENT_TYPE_SUBSCRIBE)){
                //关注，普通关注+ 扫专属二维码关注，带有qrscene_
                logger.info("wechat 关注01--" + eventKey);
                logger.info("wechat 关注02--" + eventKey);

                if (StringUtil.isEmptyOrNull(eventKey)) {
                    resMsg = messageFromSql(eventKey, WechatMessageUtil.REQUST_EVENT_TYPE_COMMON_CONCERN, fromUserName, toUserName);
                } else {
                    eventKey = eventKey.replace("qrscene_", "");
                    resMsg = messageFromSql(eventKey, WechatMessageUtil.REQUST_EVENT_TYPE_PARAMETER_FOLLOW, fromUserName, toUserName);
                }

                saveWechatUserInfoWhenFllowPublicNumber(fromUserName);
            }else if(event.equals(WechatMessageUtil.EVENT_TYPE_UNSUBSCRIBE)){
                //取消关注
                logger.info("wechat 取消关注");
            }else if(event.equals(WechatMessageUtil.EVENT_TYPE_LOCATION)){
                //上报地理位置
                //Latitude	地理位置纬度;Longitude	地理位置经度;Precision	地理位置精度
                String Latitude = requestMap.get("Latitude").toString();
                String Longitude = requestMap.get("Longitude").toString();
                String Precision = requestMap.get("Precision").toString();
                logger.info("wechat 上报地理位置: Latitude="+ Latitude + ";Longitude=" + Longitude + ";Precision=" + Precision);
            }else if(event.equals(WechatMessageUtil.EVENT_TYPE_SCANCODE_PUSH)){
                //扫码推事件的事件推送
                //EventKey	事件KEY值，由开发者在创建菜单时设定;ScanCodeInfo	扫描信息;ScanType	扫描类型，一般是qrcode;ScanResult	扫描结果，即二维码对应的字符串信息
                String ScanCodeInfo = requestMap.get("ScanCodeInfo").toString();
                String ScanType = requestMap.get("ScanType").toString();
                String ScanResult = requestMap.get("ScanResult").toString();

                resMsg = messageFromSql(eventKey, WechatMessageUtil.REQUST_EVENT_TYPE_CODE_PUSH, fromUserName, toUserName);

                logger.info("wechat 扫码推事件的事件推送: eventKey="+ eventKey + ";ScanCodeInfo=" + ScanCodeInfo + ";ScanType=" + ScanType + ";ScanResult=" + ScanResult);
            }else if(event.equals(WechatMessageUtil.EVENT_TYPE_SCANCODE_WAITING)){

                resMsg = messageFromSql(eventKey, WechatMessageUtil.REQUST_EVENT_TYPE_CODE_WAIT, fromUserName, toUserName);

                //扫码推事件且弹出“消息接收中”提示框的事件推送
                //EventKey	事件KEY值，由开发者在创建菜单时设定;ScanCodeInfo	扫描信息;ScanType	扫描类型，一般是qrcode;ScanResult	扫描结果，即二维码对应的字符串信息
                String ScanCodeInfo = requestMap.get("ScanCodeInfo").toString();
                String ScanType = requestMap.get("ScanType").toString();
                String ScanResult = requestMap.get("ScanResult").toString();
                logger.info("wechat 扫码推事件且弹出“消息接收中”提示框的事件推送: eventKey="+ eventKey + ";ScanCodeInfo=" + ScanCodeInfo + ";ScanType=" + ScanType + ";ScanResult=" + ScanResult);
            }else if(event.equals(WechatMessageUtil.EVENT_TYPE_LOCATION_SELECT)){
                //弹出地理位置选择器的事件推送
                //SendLocationInfo	发送的位置信息;Location_X	X坐标信息;Location_Y	Y坐标信息;Scale	精度，可理解为精度或者比例尺、越精细的话 scale越高;Label	地理位置的字符串信息;Poiname	朋友圈POI的名字，可能为空
                Map<String, Object> sendLocationInfoMap = (Map<String, Object>) requestMap.get("SendLocationInfo");
                String Location_X = sendLocationInfoMap.get("Location_X").toString();
                String Location_Y = sendLocationInfoMap.get("Location_Y").toString();
                String Scale = sendLocationInfoMap.get("Scale").toString();
                String Label = sendLocationInfoMap.get("Label").toString();
                String Poiname = sendLocationInfoMap.get("Poiname").toString();
                logger.info("wechat 出地理位置选择器的事件推送: Location_X="+ Location_X + ";Location_Y=" + Location_Y + ";Scale=" + Scale + ";Label=" + Label + ";Poiname=" + Poiname);
            } else {
//                logger.info("其他事件:" + requestMap.toString());
                resMsg = messageFromSql("", WechatMessageUtil.REQUST_EVENT_TYPE_DEFAULT, fromUserName, toUserName);
            }
        } else {
//            logger.info("其他消息:" + requestMap.toString());
            resMsg = messageFromSql("", WechatMessageUtil.REQUST_EVENT_TYPE_DEFAULT, fromUserName, toUserName);
        }


        if(StringUtil.isEmptyOrNull(resMsg)){
            //TODO 取默认
            resMsg = WechatMessageUtil.buildOneNew(fromUserName, toUserName,
                    "云游圈圈官方宣传平台", "欢迎您访问丽江市旅游发展委员会官方平台！", "http://m.dxoo.cn//twap/default/img/ljgc.jpg",
                    "http://u.liveapp.cn/958170?sf=01DE5D2D-2C1D-39FF-350C-9E3DCE574569&from=message&isappinstalled=0");
        }
        output(resMsg);
        return null;
    }


    /**
     * 消息处理
     * @param keyStr 消息关键字 全匹配
     * @param type 交互类型:
                            0.默认回复
                            1:关键字回复
                            2:地理位置回复
                            3:关注回复
                            4:带参关注回复
                            5:按钮交互
                            6.扫码待提示
                            7.扫码推事件
     * @return 消息字符串
     */
    private String messageFromSql(String keyStr, Integer type, String fromUserName,String toUserName) {
        String sql;
        if (type == WechatMessageUtil.REQUST_EVENT_TYPE_DEFAULT || type == WechatMessageUtil.REQUST_EVENT_TYPE_COMMON_CONCERN) {
            sql = "SELECT reply_type, id FROM qy_wechat_public_interaction WHERE `status` = '1' AND type = '" + type + "' ORDER BY update_time DESC LIMIT 1";
        } else {
            sql = "SELECT reply_type, id FROM qy_wechat_public_interaction WHERE k = '" + keyStr + "' AND `status` = '1' AND type = '" + type + "'";
        }
        try {
            WechatPublicInteraction wechatPublicInteraction = baseService.findSingleBySQL(sql, WechatPublicInteraction.class);
            if (wechatPublicInteraction == null || wechatPublicInteraction.getReplyType() == null || wechatPublicInteraction.getId() == null) {
                return "";
            }
            Integer id = wechatPublicInteraction.getId();
            String message = "";

            /* 0:纯文本  1:单图  2:单图文  3:图文列表 */
            switch (wechatPublicInteraction.getReplyType()) {
                // 纯文本
                case WechatMessageUtil.REPLY_TYPE_CONTENT: {
                    message = textMessageFromSql(id);
                } break;
                // 单图
                case WechatMessageUtil.REPLY_TYPE_IMAGE: {
                    message = imageMessageFromSql(id);
                } break;
                // 单图文
                case WechatMessageUtil.REPLY_TYPE_OME_IMAGE_CONTENT: {
                    message = buildOneNewFromSql(id, fromUserName, toUserName);
                } break;
                // 图文列表
                case WechatMessageUtil.REPLY_TYPE_MORE_IMAGE_CONTENT: {
                    message = buildMoreNewFromSql(id, fromUserName, toUserName);
                } break;
            }
            return message;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 纯文本消息处理
     * @param id 消息交互信息id
     * @return 消息字符串
     */
    private String textMessageFromSql(Integer id) {
        String sql = "SELECT * FROM qy_wechat_public_content WHERE `status`='1' AND wechat_public_interaction_id = '" + id + "'";
        TextMessage textMessage = new TextMessage();
        try {
            String content = baseService.getUniqueResultSQL(sql);
            textMessage.setContent(content);
            if (StringUtil.isEmptyOrNull(content)) {
                return "";
            }
            return WechatMessageUtil.textMessageToXml(textMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 单图处理
     * @param id 消息交互信息id
     * @return 消息字符串
     */
    private String imageMessageFromSql(Integer id) {
        ImageMessage imageMessage = new ImageMessage();
        String sql = "SELECT media_id FROM qy_wechat_public_content WHERE `status`='1' AND wechat_public_interaction_id = '" + id + "'";
        try {
            String mediaId = baseService.getUniqueResultSQL(sql);
            if (StringUtil.isEmptyOrNull(mediaId)) {
                return "";
            }
            imageMessage.setMediaId(mediaId);
            return WechatMessageUtil.imageMessageToXml(imageMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 单图文处理
     * @param id 消息交互信息id
     * @return 消息字符串
     */
    private String buildOneNewFromSql(Integer id, String fromUserName,String toUserName) {
        String sql = "SELECT content, img, title, url FROM qy_wechat_public_content WHERE `status` = '1' AND wechat_public_interaction_id = '" + id + "'";
        try {
            List<WechatPublicContent> wechatPublicContents = baseService.findBySQL(sql, WechatPublicContent.class);
            if (wechatPublicContents.size() <= 0) {
                return "";
            }
            WechatPublicContent wechatPublicContent = wechatPublicContents.get(0);
            return WechatMessageUtil.buildOneNew(fromUserName, toUserName, wechatPublicContent.getTitle(), wechatPublicContent.getContent(), wechatPublicContent.getImg(), wechatPublicContent.getUrl());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 多图文处理
     * @param id 消息交互信息id
     * @return 消息字符串
     */
    private String buildMoreNewFromSql(Integer id, String fromUserName, String toUserName) {
        String sql = "SELECT title, description, pic_url, url FROM qy_wechat_public_content WHERE `status` = '1' AND wechat_public_interaction_id = '" + id + "'";
        List<Article> articles = new ArrayList<Article>();
        try {
            List<WechatPublicContent> wechatPublicContents = baseService.findBySQL(sql, WechatPublicContent.class);
            if (wechatPublicContents.size() <= 0) {
                return "";
            }
            for (WechatPublicContent wechatPublicContent : wechatPublicContents) {
                Article article = new Article();
                article.setTitle(wechatPublicContent.getTitle());
                article.setDescription(wechatPublicContent.getDescription());
                article.setPicUrl(wechatPublicContent.getPicUrl());
                article.setUrl(wechatPublicContent.getUrl());
                articles.add(article);
            }
            return WechatMessageUtil.buildOneOrMoreNew(fromUserName, toUserName, articles);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 当用户首次关注时 将用户微信信息存入数据库
     * @param fromUserName
     */
    public void saveWechatUserInfoWhenFllowPublicNumber(String fromUserName) {
        String sql = "SELECT COUNT(id) FROM qy_wechat_userinfo WHERE openid = '" + fromUserName + "'";
        WechatUserinfo wechatUserinfo = WechatUtil.getUserInfo(redisTemplateUtil, fromUserName);
        try {
            Integer count = baseService.getRecordCountSQL(sql, WechatUserinfo.class);
            if (count <= 0) {
                baseService.save(wechatUserinfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
